// core/Colour.cpp
#include <core/std.h>
#include "Colour.h"

using namespace CORE;
using namespace Math;

Colour::Colour()
{
	m_Colour[0] = m_Colour[1] = m_Colour[2] = m_Colour[3] = 255;
}

Colour::Colour(uint8_t Red, uint8_t Green, uint8_t Blue, uint8_t Alpha)
{
	m_Colour[0] = Red;
	m_Colour[1] = Green;
	m_Colour[2] = Blue;
	m_Colour[3] = Alpha;
}

void Colour::SetColour(uint8_t Red, uint8_t Green, uint8_t Blue, uint8_t Alpha)
{
	m_Colour[0] = Red;
	m_Colour[1] = Green;
	m_Colour[2] = Blue;
	m_Colour[3] = Alpha;
}

void Colour::SetColour(const Colour & that)
{
	m_Colour[0] = that.m_Colour[0];
	m_Colour[1] = that.m_Colour[1];
	m_Colour[2] = that.m_Colour[2];
	m_Colour[3] = that.m_Colour[3];
}

const Colour & Colour::operator=(const Colour & that)
{
	m_Colour[0] = that.m_Colour[0];
	m_Colour[1] = that.m_Colour[1];
	m_Colour[2] = that.m_Colour[2];
	m_Colour[3] = that.m_Colour[3];

	return *this;
}

bool Colour::operator==(const Colour & that) const
{
	return (m_Colour[0] == that.m_Colour[0]
		&& m_Colour[1] == that.m_Colour[1]
		&& m_Colour[2] == that.m_Colour[2]
		&& m_Colour[3] == that.m_Colour[3] );
}

bool Colour::operator!=(const Colour & that) const
{
	return (m_Colour[0] != that.m_Colour[0]
		|| m_Colour[1] != that.m_Colour[1]
		|| m_Colour[2] != that.m_Colour[2]
		|| m_Colour[3] != that.m_Colour[3] );
}

Colour Colour::operator/(float fFactor) const
{
	return Colour( (uint8_t)( (float)m_Colour[0] / fFactor),
			(uint8_t)( (float)m_Colour[1] / fFactor),
			(uint8_t)( (float)m_Colour[2] / fFactor),
			(uint8_t)( (float)m_Colour[3] / fFactor) );
}

const Colour & Colour::operator/=(float fFactor)
{
	m_Colour[0] = (uint8_t)( (float)m_Colour[0] / fFactor);
	m_Colour[1] = (uint8_t)( (float)m_Colour[1] / fFactor);
	m_Colour[2] = (uint8_t)( (float)m_Colour[2] / fFactor);
	m_Colour[3] = (uint8_t)( (float)m_Colour[3] / fFactor);

	return *this;
}

Colour Colour::operator*(float fFactor) const
{
	return Colour( (uint8_t)( (float)m_Colour[0] * fFactor),
		(uint8_t)( (float)m_Colour[1] * fFactor),
		(uint8_t)( (float)m_Colour[2] * fFactor),
		(uint8_t)( (float)m_Colour[3] * fFactor) );
}

const Colour & Colour::operator*=(float fFactor)
{
	m_Colour[0] = (uint8_t)( (float)m_Colour[0] * fFactor );
	m_Colour[1] = (uint8_t)( (float)m_Colour[1] * fFactor );
	m_Colour[2] = (uint8_t)( (float)m_Colour[2] * fFactor );
	m_Colour[3] = (uint8_t)( (float)m_Colour[3] * fFactor );

	return *this;
}

Colour Colour::operator+(const Colour & that) const
{
	return Colour( (uint8_t)Tabi_Min( (uint32_t)this->m_Colour[0] + (uint32_t)that.m_Colour[0], (uint32_t)255),
					(uint8_t)Tabi_Min( (uint32_t)this->m_Colour[1] + (uint32_t)that.m_Colour[1], (uint32_t)255),
					(uint8_t)Tabi_Min( (uint32_t)this->m_Colour[2] + (uint32_t)that.m_Colour[2], (uint32_t)255),
					(uint8_t)Tabi_Min( (uint32_t)this->m_Colour[3] + (uint32_t)that.m_Colour[3], (uint32_t)255) );
}

const Colour & Colour::operator+=(const Colour & that)
{
	m_Colour[0] = (uint8_t)Tabi_Min( (uint32_t)this->m_Colour[0] + (uint32_t)that.m_Colour[0], (uint32_t)255);
	m_Colour[1] = (uint8_t)Tabi_Min( (uint32_t)this->m_Colour[1] + (uint32_t)that.m_Colour[1], (uint32_t)255);
	m_Colour[2] = (uint8_t)Tabi_Min( (uint32_t)this->m_Colour[2] + (uint32_t)that.m_Colour[2], (uint32_t)255);
	m_Colour[3] = (uint8_t)Tabi_Min( (uint32_t)this->m_Colour[3] + (uint32_t)that.m_Colour[3], (uint32_t)255);

	return *this;
}

Colour Colour::operator-(const Colour & that) const
{
	return Colour( (uint8_t)Tabi_Max( (int32_t)this->m_Colour[0] + (int32_t)that.m_Colour[0], (int32_t)0 ),
					(uint8_t)Tabi_Max( (int32_t)this->m_Colour[1] + (int32_t)that.m_Colour[1], (int32_t)0 ),
					(uint8_t)Tabi_Max( (int32_t)this->m_Colour[2] + (int32_t)that.m_Colour[2], (int32_t)0 ),
					(uint8_t)Tabi_Max( (int32_t)this->m_Colour[3] + (int32_t)that.m_Colour[3], (int32_t)0 ) );
}

const Colour & Colour::operator-=(const Colour & that)
{
	m_Colour[0] = (uint8_t)Tabi_Max( (int32_t)this->m_Colour[0] + (int32_t)that.m_Colour[0], (int32_t)0 );
	m_Colour[1] = (uint8_t)Tabi_Max( (int32_t)this->m_Colour[1] + (int32_t)that.m_Colour[1], (int32_t)0 );
	m_Colour[2] = (uint8_t)Tabi_Max( (int32_t)this->m_Colour[2] + (int32_t)that.m_Colour[2], (int32_t)0 );
	m_Colour[3] = (uint8_t)Tabi_Max( (int32_t)this->m_Colour[3] + (int32_t)that.m_Colour[3], (int32_t)0 );

	return *this;
}